﻿using System;
using System.Windows.Controls;
using Granite.Xaml;
using Granite.Xaml.Converters;

namespace Toon
{
	/// <summary>
	/// 
	/// </summary>
	public static class ViewUtilities
	{

		/// <summary>
		/// Adds a value converter to the static resource collection.
		/// </summary>
		/// <param name="control"></param>
		/// <param name="converterName"></param>
		/// <param name="convert"></param>
		/// <param name="convertBack"></param>
		/// <remarks>This must be called before the control is initialized</remarks>
		public static void AddConverter<TSource, TTarget>(this Control control, string converterName, Func<TSource, TTarget> convert, Func<TTarget, TSource> convertBack = null)
		{
			if (control == null)
				throw new ArgumentNullException("control", "control is null.");
			if (String.IsNullOrEmpty(converterName))
				throw new ArgumentException("converterName is null or empty.", "converterName");
			if (convert == null)
				throw new ArgumentNullException("convert", "convert is null.");

			Func<object, object> convert2 = v => convert((TSource)v);
			Func<object, object> convertBack2;
			if (convertBack != null)
				convertBack2 = v => convertBack((TTarget)v);
			else
				convertBack2 = null;


			control.Resources.Add(converterName, new DelegateConverter(convert2, convertBack2));
		}

		/// <summary>
		/// Adds a value converter to the static resource collection.
		/// </summary>
		/// <param name="control"></param>
		/// <param name="converterName"></param>
		/// <param name="convert"></param>
		/// <param name="convertBack"></param>
		/// <remarks>This must be called before the control is initialized</remarks>
		public static void AddConverter(this Control control, string converterName, Func<object, object> convert, Func<object, object> convertBack = null)
		{
			if (control == null)
				throw new ArgumentNullException("control", "control is null.");
			if (String.IsNullOrEmpty(converterName))
				throw new ArgumentException("converterName is null or empty.", "converterName");
			if (convert == null)
				throw new ArgumentNullException("convert", "convert is null.");

			control.Resources.Add(converterName, new DelegateConverter(convert, convertBack));
		}

		/// <summary>
		/// Adds a value converter to the static resource collection.
		/// </summary>
		/// <param name="control"></param>
		/// <param name="converterName"></param>
		/// <param name="convert"></param>
		/// <param name="convertBack"></param>
		/// <remarks>This must be called before the control is initialized</remarks>
		public static void AddConverter(this Control control, string converterName, ValueConversion convert, ValueConversion convertBack = null)
		{
			if (control == null)
				throw new ArgumentNullException("control", "control is null.");
			if (String.IsNullOrEmpty(converterName))
				throw new ArgumentException("converterName is null or empty.", "converterName");
			if (convert == null)
				throw new ArgumentNullException("convert", "convert is null.");

			control.Resources.Add(converterName, new DelegateConverter(convert, convertBack));
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="control"></param>
		/// <param name="commandName"></param>
		/// <param name="command"></param>
		public static void AddCommand(this Control control, string commandName, Action command)
		{
			if (control == null)
				throw new ArgumentNullException("control", "control is null.");
			if (String.IsNullOrEmpty(commandName))
				throw new ArgumentException("commandName is null or empty.", "commandName");
			if (command == null)
				throw new ArgumentNullException("command", "command is null.");

			control.Resources.Add(commandName, new DelegateCommand(command));
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="control"></param>
		/// <param name="commandName"></param>
		/// <param name="command"></param>
		public static void AddCommand(this Control control, string commandName, Action<object> command)
		{
			if (control == null)
				throw new ArgumentNullException("control", "control is null.");
			if (String.IsNullOrEmpty(commandName))
				throw new ArgumentException("commandName is null or empty.", "commandName");
			if (command == null)
				throw new ArgumentNullException("command", "command is null.");

			control.Resources.Add(commandName, new DelegateCommand(command));
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="control"></param>
		/// <param name="commandName"></param>
		/// <param name="command"></param>
		public static void AddCommand<T>(this Control control, string commandName, Action<T> command)
		{
			if (control == null)
				throw new ArgumentNullException("control", "control is null.");
			if (String.IsNullOrEmpty(commandName))
				throw new ArgumentException("commandName is null or empty.", "commandName");
			if (command == null)
				throw new ArgumentNullException("command", "command is null.");

			control.Resources.Add(commandName, new DelegateCommand(p => command((T)p)));
		}

	}
}
